package com.tinem.platform.web.netty.websocket.message;

import cn.hutool.core.util.StrUtil;
import com.tinem.platform.module.pojo.co.RedisKeyEnum;
import com.tinem.platform.module.pojo.enums.message.Message;
import com.tinem.platform.module.starter.jms.consumer.ConsumerService;
import com.tinem.platform.module.starter.jms.consumer.SubscribeListener;
import com.tinem.platform.module.starter.jms.enums.TopicEnum;
import com.tinem.platform.module.starter.jms.util.impl.JmsTopicUtil;
import com.tinem.platform.module.starter.sdk.page.PlatformJwt;
import com.tinem.platform.module.starter.sdk.util.JwtUtil;
import com.tinem.platform.web.netty.websocket.session.Session;
import com.tinem.platform.web.netty.websocket.util.MessageUtil;
import io.netty.channel.ChannelHandlerContext;
import lombok.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.concurrent.TimeUnit;

/**
 * @author fengzhihao
 * @version v1
 * @program: platform
 * @className EchoCommand
 * @description TODO
 * @site
 * @company
 * @create 2021/11/30 19:30:48
 */
@Slf4j
@Service("command_auth")
public class AuthCommand implements Command{

    @Value("${spring.application.name}")
    protected String name;
    @Value("${spring.profiles.active}")
    protected String active;
    @Resource
    JwtUtil jwtUtil;

    @Resource
    ConsumerService consumerService;

    @Resource
    StringRedisTemplate stringRedisTemplate;

    @Resource
    JmsTopicUtil jmsTopicUtil;

    @SneakyThrows
    @Override
    public void call(ChannelHandlerContext ctx, Message message) {

        Auth auth = message.getReq().toJavaObject(Auth.class);
        if(StrUtil.isEmpty(auth.getToken())){
            message.setRes(auth);
            MessageUtil.sendMessage(ctx,message,false,"token is not empty");
            return;
        }
        PlatformJwt jwt = jwtUtil.getDecodedJWT(auth.getToken());
        String connectionId = consumerService.subscribeTopic(TopicEnum.getUserTopic(active,name,jwt.getUserId()), new SubscribeListener<Message>() {
            @Override
            public void call(Message message1) {
                MessageUtil.sendMessage(ctx, message1);
            }
        });
        Session.addConsumerId(ctx,connectionId);

        connectionId = consumerService.subscribeTopic(TopicEnum.getAllUser(active,name), new SubscribeListener<Message>() {
            @Override
            public void call(Message message1) {
                MessageUtil.sendMessage(ctx, message1);
            }
        });
        Session.addConsumerId(ctx,connectionId);

        //给用户在线的session 数量加1
        String key = RedisKeyEnum.websocket_user_online.getKey(jwt.getUserId());
        Long sessinNum = stringRedisTemplate.opsForValue().increment(key);
        stringRedisTemplate.expire(key,24, TimeUnit.HOURS);
        log.debug("user online num:({}):({})",sessinNum,RedisKeyEnum.websocket_user_online.getKey(jwt.getUserId()));
        if(sessinNum == 1){
            //用户上线
            log.info("user({}) online",jwt.getUserId());
            jmsTopicUtil.sendMessage(jwt.getUserId(),name,TopicEnum.WEB_SOCKET_USER_ONLINE,jwt.getClientId());
        }

        Session session = Session.getSession(ctx);
        session.setJwt(jwt);
        Session.auth(session);

        auth.setUserId(jwt.getUserId());
        message.setRes(auth);
        MessageUtil.sendMessage(ctx,message);
        return;

    }
    @Data
    @Builder
    @NoArgsConstructor
    @AllArgsConstructor
    public static class Auth{
        String token;
        String userId;
    }
}
